package com.myMinistry.gui;

import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;

import android.app.DatePickerDialog;
import android.app.Dialog;
import android.content.ContentValues;
import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
import android.database.Cursor;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentActivity;
import android.support.v4.app.FragmentTransaction;
import android.view.KeyEvent;
import android.view.View;
import android.widget.Button;
import android.widget.DatePicker;
import android.widget.Toast;

import com.myMinistry.Helper;
import com.myMinistry.R;
import com.myMinistry.provider.MinistryContract.EntryType;
import com.myMinistry.provider.MinistryContract.Householder;
import com.myMinistry.provider.MinistryContract.Literature;
import com.myMinistry.provider.MinistryContract.LiteraturePlaced;
import com.myMinistry.provider.MinistryContract.Rollover;
import com.myMinistry.provider.MinistryContract.Time;
import com.myMinistry.provider.MinistryService;

public class TimeEditor extends FragmentActivity {
	private MinistryService database;
	private final SimpleDateFormat dateFormat = new SimpleDateFormat("EEEE, MMMM d, yyyy");
    private final SimpleDateFormat timeFormat = new SimpleDateFormat("h:mm aaa");
    private Button timeStart, timeEnd, date, entryType;
    private ArrayList<LitEntry> selectedLiterature = new ArrayList<LitEntry>();
    
    private Cursor recordRO, allLit, rollOverRecord;
	
	private SharedPreferences sharedPref;
	
	private int timeID = 0;
	private int publisherID = 0;
	private int originalPublisherID = 0;
	private final Calendar selectedDate = Calendar.getInstance();
	private final Calendar previousSelectedDate = Calendar.getInstance();
	private final Calendar selectedTimeStart = Calendar.getInstance();
	private final Calendar selectedTimeEnd = Calendar.getInstance();
	private double totalHours = 0;
	private int entryTypeID = 0;
	private String entryTypeName;
	private int householderID = 0;
	private String householderName;
	private int returnVisitCount = 0;
	
	private int typeOfLiteratureID = 0;
	private int literatureID = 0;
	private String literatureName = "";
	
	private boolean isLiteratureEdit = false;
	private int isLiteratureEditID = 0;
	
	SimpleDateFormat saveDateFormat	= new SimpleDateFormat("yyyy-MM-dd");
	SimpleDateFormat saveTimeFormat	= new SimpleDateFormat("HH:mm");
	
	@Override
	public void onStop() {
		super.onStop();
		/** Close all cursors and then the database */
		if(recordRO != null && !recordRO.isClosed())
			recordRO.close();
		if(allLit != null && !allLit.isClosed())
			allLit.close();
		if(rollOverRecord != null && !rollOverRecord.isClosed())
			rollOverRecord.close();
		database.close();
    }
	
	@Override
	public void onStart() {
    	super.onStart();
    	publisherID = sharedPref.getInt(Summary.MY_PREFS_KEY_PUBLISHER_ID, 0);
    	originalPublisherID = publisherID;
    	/** There is a time to display, so lets get the info about it */
    	if(timeID > 0) {
    		database.openReadable();
    		Cursor record = database.fetchTimeEntry(timeID);
    		if(record.moveToFirst()) {
    			entryTypeID = record.getInt(record.getColumnIndex(Time.ENTRY_TYPE_ID));
    			householderID = record.getInt(record.getColumnIndex(Time.HOUSEHOLDER_ID));
    			String[] splitDate = record.getString(record.getColumnIndex(Time.DATE)).split("-");
    			selectedDate.set(Calendar.YEAR, Integer.valueOf(splitDate[0]));
    			previousSelectedDate.set(Calendar.YEAR, Integer.valueOf(splitDate[0]));
    			/** Needs to be subtracted because months are zero based */
    			selectedDate.set(Calendar.MONTH, Integer.valueOf(splitDate[1]) - 1);
    			selectedDate.set(Calendar.DAY_OF_MONTH, Integer.valueOf(splitDate[2]));
    			previousSelectedDate.set(Calendar.MONTH, Integer.valueOf(splitDate[1]) - 1);
    			previousSelectedDate.set(Calendar.DAY_OF_MONTH, Integer.valueOf(splitDate[2]));
    			String[] splitTime = record.getString(record.getColumnIndex(Time.TIME_START)).split(":");
    			selectedTimeStart.set(Calendar.HOUR_OF_DAY,Integer.valueOf(splitTime[0]));
    			selectedTimeStart.set(Calendar.MINUTE,Integer.valueOf(splitTime[1]));
    			splitTime = record.getString(record.getColumnIndex(Time.TIME_END)).split(":");
    			selectedTimeEnd.set(Calendar.HOUR_OF_DAY,Integer.valueOf(splitTime[0]));
    			selectedTimeEnd.set(Calendar.MINUTE,Integer.valueOf(splitTime[1]));
    			returnVisitCount = record.getInt(record.getColumnIndex(Time.RETURN_VISITS));
    		}
    		record.close();
    		Cursor litRecords = database.fetchLiteratureByTimeID(timeID);
    		while(litRecords.moveToNext()) {
    			LitEntry thisEntry = new LitEntry(litRecords.getInt(litRecords.getColumnIndex(LiteraturePlaced._ID))
    												,litRecords.getString(litRecords.getColumnIndex(Literature.NAME))
    												,litRecords.getInt(litRecords.getColumnIndex(LiteraturePlaced.LITERATURE_ID))
    												,litRecords.getInt(litRecords.getColumnIndex(LiteraturePlaced.COUNT)));
    			
    			thisEntry.setPublisherID(litRecords.getInt(litRecords.getColumnIndex(LiteraturePlaced.PUBLISHER_ID)));
    			thisEntry.setHouseholderID(litRecords.getInt(litRecords.getColumnIndex(LiteraturePlaced.HOUSEHOLDER_ID)));
    			selectedLiterature.add(thisEntry);
    		}
    		populateList(selectedLiterature);
    		litRecords.close();
    		
    		if(entryTypeID > 0) {
    			record = database.fetchEntryType(entryTypeID);
    			if(record.moveToFirst())
    				entryTypeName = record.getString(record.getColumnIndex(EntryType.NAME));
    			record.close();
    		}
    		
    		if(householderID > 0) {
    			record = database.fetchHouseholder(householderID);
    			if(record.moveToFirst())
    				updateHouseholder(householderID, record.getString(record.getColumnIndex(Householder.NAME)));
    			record.close();
    			
    		}
    		
			if(returnVisitCount > 0)
				updateRVCount(returnVisitCount);
			
			if(entryType.getText().length() == 0)
				entryType.setText(entryTypeName);
    		
			database.close();
    	}
    	else {
    		if(selectedDate.get(Calendar.AM_PM) == Calendar.PM && selectedTimeEnd.get(Calendar.HOUR_OF_DAY) < 12)
    			selectedTimeEnd.set(Calendar.HOUR_OF_DAY, selectedTimeEnd.get(Calendar.HOUR_OF_DAY) + 12);
			selectedTimeEnd.set(Calendar.MINUTE, Helper.roundMinutes(selectedTimeEnd.get(Calendar.MINUTE)));
			/** If the time jumped to the next hour because of the minutes rounding. */
			if(selectedTimeEnd.get(Calendar.MINUTE) == 0 && selectedTimeEnd.get(Calendar.MINUTE) > 50)
				selectedTimeEnd.set(Calendar.HOUR_OF_DAY, selectedTimeEnd.get(Calendar.HOUR_OF_DAY) + 1);
			selectedTimeStart.set(Calendar.MINUTE, selectedTimeEnd.get(Calendar.MINUTE));
			selectedTimeStart.set(Calendar.HOUR_OF_DAY, selectedTimeEnd.get(Calendar.HOUR_OF_DAY) - 1);
			entryType.setText(entryTypeName);
    	}
    	
    	selectedTimeStart.set(Calendar.SECOND, 0);
    	selectedTimeStart.set(Calendar.MILLISECOND, 0);
    	selectedTimeEnd.set(Calendar.SECOND, 0);
    	selectedTimeEnd.set(Calendar.MILLISECOND, 0);
    	
    	date.setText(dateFormat.format(selectedDate.getTime()).toString());
    	timeStart.setText(timeFormat.format(selectedTimeStart.getTime()).toString());
    	timeEnd.setText(timeFormat.format(selectedTimeEnd.getTime()).toString());
    }
    
    @Override
    public boolean onKeyDown(int keyCode, KeyEvent event) {
        if ((keyCode == KeyEvent.KEYCODE_BACK)) {
    		Intent intent = new Intent(getApplicationContext(), Summary.class);
			intent.putExtra("month", selectedDate.get(Calendar.MONTH));
			intent.putExtra("year", selectedDate.get(Calendar.YEAR));
			startActivity(intent);
			finish();
        }
        return super.onKeyDown(keyCode, event);
    }
    
    @Override
	public void onCreate(Bundle savedInstanceState) {
    	super.onCreate(savedInstanceState);
    	Bundle extras = getIntent().getExtras();
    	setContentView(R.layout.time_editor);
    	
    	/** Setup database */
    	database = new MinistryService(this);
    	
    	if(extras != null) {
	    	Object[] keys = extras.keySet().toArray();
	    	for(int i = 0; i < keys.length; i++) {
	    		if(keys[i].toString().equals("timeID"))
	    			timeID = extras.getInt("timeID");
	    	}
    	}
    	
    	/** Get objects from view layout */
    	timeStart = (Button) findViewById(R.id.timeStart);
    	timeEnd = (Button) findViewById(R.id.timeEnd);
    	date = (Button) findViewById(R.id.date);
    	entryType = (Button) findViewById(R.id.entryType);
    	
    	/** Default text */
    	entryTypeName = getApplicationContext().getString(R.string.typeOfService);
    	householderName = getApplicationContext().getString(R.string.selectAHouseholder);

    	date.setOnClickListener(new View.OnClickListener() { public void onClick(View v) { showDialog(0); } });
    	entryType.setOnClickListener(new showEntryTypes());
    	
    	sharedPref = getSharedPreferences(Summary.MY_PREFS, Context.MODE_PRIVATE);
	}
    
    /** What to do for our on creation date and timer buttons or dialogs if you will */
    @Override
	protected Dialog onCreateDialog(int id) {
        return new DatePickerDialog(this, mDateSetListener, selectedDate.get(Calendar.YEAR), selectedDate.get(Calendar.MONTH), selectedDate.get(Calendar.DAY_OF_MONTH));
    }
    
    /** Set the date the user selected into our global variables */
    private final DatePickerDialog.OnDateSetListener mDateSetListener = new DatePickerDialog.OnDateSetListener() {
    	public void onDateSet(DatePicker view, int year, int monthOfYear, int dayOfMonth) {
    		selectedDate.set(Calendar.YEAR, year);
    		selectedDate.set(Calendar.MONTH, monthOfYear);
    		selectedDate.set(Calendar.DAY_OF_MONTH, dayOfMonth);
    		date.setText(dateFormat.format(selectedDate.getTime()).toString());
        }
    };
	
	/** Insert values into database */
	private boolean saveTime() {
		/** Flag to know if the literature should be inserted or deleted */
		boolean isnew = false;
		
		/** We need to get the hours for the entry */
		/** Compare values
		 *  0 if the times of the two Calendars are equal
		 *  -1 if the time of this Calendar is before the other one
		 *  1 if the time of this Calendar is after the other one
		 */
		Calendar calendar = Calendar.getInstance();
		calendar.set(Calendar.HOUR_OF_DAY, selectedTimeStart.get(Calendar.HOUR_OF_DAY));
		calendar.set(Calendar.MINUTE, selectedTimeStart.get(Calendar.MINUTE));
		calendar.set(Calendar.SECOND, selectedTimeStart.get(Calendar.SECOND));
		calendar.set(Calendar.MILLISECOND, selectedTimeStart.get(Calendar.MILLISECOND));
		totalHours = 0;
		while(selectedTimeEnd.compareTo(calendar) == 1) {
			totalHours += 0.25;
			calendar.add(Calendar.MINUTE, 15);
		}
		
		/** No zero hours allowed */
		if(totalHours <= 0) {
			Toast.makeText(getBaseContext(), R.string.zeroTimeError, Toast.LENGTH_LONG).show();
			return false;
		}
		/** Must have entry type selected. */
		else if(entryTypeID == 0) {
			Toast.makeText(getBaseContext(), R.string.entryTypeError, Toast.LENGTH_LONG).show();
			return false;
		}
		else {
			/** Values to save */
			ContentValues values = new ContentValues();
			values.put(Time.PUBLISHER_ID, publisherID);
			values.put(Time.HOUSEHOLDER_ID, householderID);
			values.put(Time.ENTRY_TYPE_ID, entryTypeID);
			values.put(Time.DATE, saveDateFormat.format(selectedDate.getTime()));
			values.put(Time.TIME_START, saveTimeFormat.format(selectedTimeStart.getTime()));
			values.put(Time.TIME_END, saveTimeFormat.format(selectedTimeEnd.getTime()));
			values.put(Time.TOTAL_HOURS, totalHours);
			values.put(Time.RETURN_VISITS, returnVisitCount);
			/** Hack because after saving date it jumps to the first of the next month when saving to placed literature... weird... */
			Calendar litPlacedDate = Calendar.getInstance();
			litPlacedDate.set(Calendar.YEAR, selectedDate.get(Calendar.YEAR));
			litPlacedDate.set(Calendar.MONTH, selectedDate.get(Calendar.MONTH));
			litPlacedDate.set(Calendar.DAY_OF_MONTH, selectedDate.get(Calendar.DAY_OF_MONTH));
			
			/** Is this a new entry or an edit of an entry? */
			if(timeID == 0) {
				isnew = true;
				database.openWritable();
				long newID = database.createTimeEntry(values);
				database.close();
				if(newID > 0) {
			    	/** A time entry was created */
				    timeID = (int)newID;
			    }
			}
			else {
				database.openWritable();
				database.updateTimeEntry(timeID, values);
				database.close();
			}
			
			/** Do we need to check for two publishers for the changing of the guard? :) */
	    	if(!isnew && publisherID != originalPublisherID) {
	    		/** Run the rollover checkup on the original publisher. */
	    		processRolloverTime(originalPublisherID, previousSelectedDate);
	    	}
	    	
    		processRolloverTime(publisherID, selectedDate);
			
			/** Literature was removed from an existing time entry. */
			if(selectedLiterature.size() == 0 && !isnew) {
				database.openWritable();
				database.deletePlacedLiteratureByTimeAndIDs("0", timeID);
				database.close();
			}
			
			String ids = "";
			/** Create new entries for the literature */
			for(LitEntry litEntry : selectedLiterature) {
				/** Values to save */
				values = new ContentValues();
				values.put(LiteraturePlaced.PUBLISHER_ID, publisherID);
				values.put(LiteraturePlaced.LITERATURE_ID, litEntry.getLitNameID());
				values.put(LiteraturePlaced.HOUSEHOLDER_ID, householderID);
				values.put(LiteraturePlaced.TIME_ID, timeID);
				values.put(LiteraturePlaced.COUNT, litEntry.getCount());
				values.put(LiteraturePlaced.MAG_MONTH, litPlacedDate.get(Calendar.MONTH));
				values.put(LiteraturePlaced.MAG_YEAR, litPlacedDate.get(Calendar.YEAR));
				values.put(LiteraturePlaced.DATE, saveDateFormat.format(litPlacedDate.getTime()));
				
				if(isnew) {
					/** No need to save the IDs since they won't be used for anything because this is a new time entry. */
					database.openWritable();
					database.createPlacedLiterature(values);
					database.close();
				}
				else {
					if(litEntry.getID() == 0) {
						database.openWritable();
						long newID = database.createPlacedLiterature(values);
						database.close();
						if(ids.length() > 1)
							ids.concat("," + String.valueOf(newID));
						else
							ids = String.valueOf(newID);
					}
					else {
						database.openWritable();
						database.updatePlacedLiterature(litEntry.getID(), values);
						database.close();
						if(ids.length() > 1)
							ids.concat("," + String.valueOf(litEntry.getID()));
						else
							ids = String.valueOf(litEntry.getID());
					}
					
					/** Now we need to cleanup any old placed literature entries */
					database.openWritable();
					database.deletePlacedLiteratureByTimeAndIDs(ids, timeID);
					database.close();
				}
			}
			Toast.makeText(getBaseContext(), R.string.timeSaved, Toast.LENGTH_LONG).show();
			return true;
		}
	}
	
	// Dynamically create the layouts for the ArrayList literature objects.
	//METHOD WHICH WILL HANDLE DYNAMIC INSERTION
	public void addEntry(LitEntry entry) {
		PlacedLiteratureListFrag fragment = (PlacedLiteratureListFrag)getSupportFragmentManager().findFragmentById(R.id.listFragment);
		fragment.addEntry(entry);
		
	}
	
	public void updateEntry(LitEntry entry, int which) {
		PlacedLiteratureListFrag fragment = (PlacedLiteratureListFrag)getSupportFragmentManager().findFragmentById(R.id.listFragment);
		fragment.updateEntry(entry, which);
	}
	
	public void removeEntry() {
		PlacedLiteratureListFrag fragment = (PlacedLiteratureListFrag)getSupportFragmentManager().findFragmentById(R.id.listFragment);
		fragment.removeEntry(isLiteratureEditID);
	}
	
	public void populateList(ArrayList<LitEntry> thisList) {
		if(!thisList.isEmpty()) {
			PlacedLiteratureListFrag fragment = (PlacedLiteratureListFrag)getSupportFragmentManager().findFragmentById(R.id.listFragment);
			fragment.populateList(thisList);
		}
	}
    
    /** Show DialogFrag on item selected */
	public class showEntryTypes implements android.view.View.OnClickListener {
		@Override
		public void onClick(View v) {
			/** DialogFragment.show() will take care of adding the fragment
			 * in a transaction. We also want to remove any currently showing
			 * dialogs, so make our own transaction and take care of that here. */
			FragmentTransaction ft = getSupportFragmentManager().beginTransaction();
			Fragment prev = getSupportFragmentManager().findFragmentByTag("dialog");
			if(prev != null)
				ft.remove(prev);
			ft.addToBackStack(null);
			/** Create and show the dialog. */
			DialogFrag newFragment = DialogFrag.newInstance(getApplicationContext().getString(R.string.entryTypes), DialogFrag.ENTRY_TYPES);
			newFragment.show(getSupportFragmentManager(), "dialog");
		}
	}
    
    /** Show DialogFrag on item selected */
	public class showHouseholders implements android.view.View.OnClickListener {
		@Override
		public void onClick(View v) {
			showHouseholdersDialog();
		}
	}
    
    /** Show DialogFragTimeSelected on item selected */
	public void showTimeStartDialog(View v) {
		/** DialogFragment.show() will take care of adding the fragment
		 * in a transaction. We also want to remove any currently showing
		 * dialogs, so make our own transaction and take care of that here. */
		FragmentTransaction ft = getSupportFragmentManager().beginTransaction();
		Fragment prev = getSupportFragmentManager().findFragmentByTag("dialog");
		if(prev != null)
			ft.remove(prev);
		ft.addToBackStack(null);
		/** Create and show the dialog. */
		DialogFragTimeSelector newFragment = DialogFragTimeSelector.newInstance(getApplicationContext().getString(R.string.startTime), DialogFragTimeSelector.TIME_START, selectedTimeStart.get(Calendar.HOUR_OF_DAY), selectedTimeStart.get(Calendar.MINUTE));
		newFragment.show(getSupportFragmentManager(), "dialog");
	}
    
    /** Show DialogFragTimeSelected on item selected */
	public void showTimeEndDialog(View v) {
		/** DialogFragment.show() will take care of adding the fragment
		 * in a transaction. We also want to remove any currently showing
		 * dialogs, so make our own transaction and take care of that here. */
		FragmentTransaction ft = getSupportFragmentManager().beginTransaction();
		Fragment prev = getSupportFragmentManager().findFragmentByTag("dialog");
		if(prev != null)
			ft.remove(prev);
		ft.addToBackStack(null);
		/** Create and show the dialog. */
		DialogFragTimeSelector newFragment = DialogFragTimeSelector.newInstance(getApplicationContext().getString(R.string.endTime), DialogFragTimeSelector.TIME_END, selectedTimeEnd.get(Calendar.HOUR_OF_DAY), selectedTimeEnd.get(Calendar.MINUTE));
		newFragment.show(getSupportFragmentManager(), "dialog");
	}
	
	private void showHouseholdersDialog() {
		/** DialogFragment.show() will take care of adding the fragment
		 * in a transaction. We also want to remove any currently showing
		 * dialogs, so make our own transaction and take care of that here. */
		FragmentTransaction ft = getSupportFragmentManager().beginTransaction();
		Fragment prev = getSupportFragmentManager().findFragmentByTag("dialog");
		if(prev != null)
			ft.remove(prev);
		ft.addToBackStack(null);
		/** Create and show the dialog. */
		DialogFrag newFragment = DialogFrag.newInstance(getApplicationContext().getString(R.string.menuHouseholders), DialogFrag.ACTIVE_HOUSEHOLDERS);
		newFragment.show(getSupportFragmentManager(), "dialog");
	}
	
	public void showReturnVisitsDialog() {
		/** DialogFragment.show() will take care of adding the fragment
		 * in a transaction. We also want to remove any currently showing
		 * dialogs, so make our own transaction and take care of that here. */
		FragmentTransaction ft = getSupportFragmentManager().beginTransaction();
		Fragment prev = getSupportFragmentManager().findFragmentByTag("dialog");
		if(prev != null)
			ft.remove(prev);
		ft.addToBackStack(null);
		/** Create and show the dialog. */
		DialogFrag newFragment = DialogFrag.newInstance(getApplicationContext().getString(R.string.returnVisitsOneLine), DialogFrag.NUMBER_PICKER_WITH_ZERO);
		newFragment.show(getSupportFragmentManager(), "dialog");
	}
	
	public void createNewHouseholderShowDialog() {
		/** DialogFragment.show() will take care of adding the fragment
		 * in a transaction. We also want to remove any currently showing
		 * dialogs, so make our own transaction and take care of that here. */
		FragmentTransaction ft = getSupportFragmentManager().beginTransaction();
		Fragment prev = getSupportFragmentManager().findFragmentByTag("dialog");
		if(prev != null)
			ft.remove(prev);
		ft.addToBackStack(null);
		/** Create and show the dialog. */
		DialogFrag newFragment = DialogFrag.newInstance(getApplicationContext().getString(R.string.createHouseholder), DialogFrag.CREATE_HOUSEHOLDER);
		newFragment.show(getSupportFragmentManager(), "dialog");
	}
	
	public void createNewLiteratureShowDialog() {
		/** DialogFragment.show() will take care of adding the fragment
		 * in a transaction. We also want to remove any currently showing
		 * dialogs, so make our own transaction and take care of that here. */
		FragmentTransaction ft = getSupportFragmentManager().beginTransaction();
		Fragment prev = getSupportFragmentManager().findFragmentByTag("dialog");
		if(prev != null)
			ft.remove(prev);
		ft.addToBackStack(null);
		/** Create and show the dialog. */
		DialogFrag newFragment = DialogFrag.newInstance(getApplicationContext().getString(R.string.literature), DialogFrag.CREATE_LITERATURE, publisherID, typeOfLiteratureID);
		newFragment.show(getSupportFragmentManager(), "dialog");
	}
	
	public void updateEntryType(int _id, String name, boolean showHouseholderViews) {
		entryTypeID = _id;
		entryTypeName = name;
		entryType.setText(entryTypeName);
		if(showHouseholderViews) {
			/** Reset variables */
			updateHouseholder(0, "");
			returnVisitCount = 0;
			householderID = 0;
			householderName = "";
			showHouseholdersDialog();
		}
		else {
			/** Reset variables */
			returnVisitCount = 0;
			householderID = 0;
			householderName = "";
			showReturnVisitsDialog();
		}
	}
	
	public void updateHouseholder(int _id, String name) {
		householderID = _id;
		householderName = name;
		if(householderName.length() > 0)
			entryType.setText(entryTypeName + " " + getApplicationContext().getString(R.string.with) + " " + householderName);
		else
			entryType.setText(entryTypeName);
	}
	
	public void updateRVCount(int _count) {
		returnVisitCount = _count;
		if(returnVisitCount > 0)
			entryType.setText(entryTypeName + " " + getApplicationContext().getString(R.string.with) + " " + getResources().getQuantityString(R.plurals.numberOfReturnVisits, returnVisitCount, returnVisitCount));
		else
			entryType.setText(entryTypeName);
	}
	
	public void updateTimeStart(int _hour, int _minutes) {
		selectedTimeStart.set(Calendar.HOUR_OF_DAY, _hour);
		selectedTimeStart.set(Calendar.MINUTE, _minutes);
		timeStart.setText(timeFormat.format(selectedTimeStart.getTime()).toString());
	}
	
	public void updateTimeEnd(int _hour, int _minutes) {
		selectedTimeEnd.set(Calendar.HOUR_OF_DAY, _hour);
		selectedTimeEnd.set(Calendar.MINUTE, _minutes);
		timeEnd.setText(timeFormat.format(selectedTimeEnd.getTime()).toString());
	}
	
	public void updatePublisher(int newPublisherID, String publisherName) {
		/** Update display name from fragment */
		ActionBarFragment fragment = (ActionBarFragment)getSupportFragmentManager().findFragmentById(R.id.action_bar_fragment);
		fragment.setSelectedPublisherNameText(publisherName);
		
		/** Update local variable and update the summary info */
		publisherID = newPublisherID;
	}
	
	public void showTypesOfLiterature() {
		/** DialogFragment.show() will take care of adding the fragment
		 * in a transaction. We also want to remove any currently showing
		 * dialogs, so make our own transaction and take care of that here. */
		FragmentTransaction ft = getSupportFragmentManager().beginTransaction();
		Fragment prev = getSupportFragmentManager().findFragmentByTag("dialog");
		if(prev != null)
			ft.remove(prev);
		ft.addToBackStack(null);
		/** Create and show the dialog. */
		DialogFrag newFragment = DialogFrag.newInstance(getApplicationContext().getString(R.string.literatureType), DialogFrag.TYPES_OF_LITERATURE);
		newFragment.show(getSupportFragmentManager(), "dialog");
	}
	
	public void showTypesOfLiteratureWithRemove(String litName) {
		/** DialogFragment.show() will take care of adding the fragment
		 * in a transaction. We also want to remove any currently showing
		 * dialogs, so make our own transaction and take care of that here. */
		FragmentTransaction ft = getSupportFragmentManager().beginTransaction();
		Fragment prev = getSupportFragmentManager().findFragmentByTag("dialog");
		if(prev != null)
			ft.remove(prev);
		ft.addToBackStack(null);
		/** Create and show the dialog. */
		DialogFrag newFragment = DialogFrag.newInstance(getApplicationContext().getString(R.string.literatureType), DialogFrag.TYPES_OF_LITERATURE_WITH_REMOVE, litName);
		newFragment.show(getSupportFragmentManager(), "dialog");
	}
	
	public void removeLiteratureSelected() {
		if(isLiteratureEdit)
			removeEntry();
		isLiteratureEdit = false;
	}
	
	public void typeOfLiteratureSelected(int typeOfLitID, String typeOfLitName) {
		typeOfLiteratureID = typeOfLitID;
		/** DialogFragment.show() will take care of adding the fragment
		 * in a transaction. We also want to remove any currently showing
		 * dialogs, so make our own transaction and take care of that here. */
		FragmentTransaction ft = getSupportFragmentManager().beginTransaction();
		Fragment prev = getSupportFragmentManager().findFragmentByTag("dialog");
		if(prev != null)
			ft.remove(prev);
		ft.addToBackStack(null);
		/** Create and show the dialog. */
		DialogFrag newFragment = DialogFrag.newInstance(typeOfLitName, DialogFrag.LITERATURE_BY_TYPE, publisherID, typeOfLitID);
		newFragment.show(getSupportFragmentManager(), "dialog");
	}
	
	public void updateLiteratureSelected(int litID, String litName) {
		literatureID = litID;
		literatureName = litName;
		// now we need to give them the option of the month/year and count of literature...
		/** DialogFragment.show() will take care of adding the fragment
		 * in a transaction. We also want to remove any currently showing
		 * dialogs, so make our own transaction and take care of that here. */
		FragmentTransaction ft = getSupportFragmentManager().beginTransaction();
		Fragment prev = getSupportFragmentManager().findFragmentByTag("dialog");
		if(prev != null)
			ft.remove(prev);
		ft.addToBackStack(null);
		/** Create and show the dialog. */
		DialogFrag newFragment = DialogFrag.newInstance(getApplicationContext().getString(R.string.howMany), DialogFrag.NUMBER_PICKER);
		newFragment.show(getSupportFragmentManager(), "dialog");
	}
	
	public void updateLiteratureSelectedCount(int count) {
		if(isLiteratureEdit)
			updateEntry(new LitEntry(0, literatureName, literatureID, count), isLiteratureEditID);
		else
			addEntry(new LitEntry(0, literatureName, literatureID, count));
		
		/** Reset edit variable */
		isLiteratureEdit = false;
	}
	
	public void changeLitEntry(int which, String litName) {
		isLiteratureEdit = true;
		isLiteratureEditID = which;
		showTypesOfLiteratureWithRemove(litName);
	}
    
    private void processRolloverTime(int _publisherID, Calendar _startDate) {
    	Calendar roDate = _startDate;
    	Calendar stopDate = Calendar.getInstance();
    	double sum = 0;
    	double currentMinutes = 0;
    	double previousMinutes = 0;
    	int rolloverTimeID = 0;
    	int rolloverID = 0;
    	ContentValues timeValues = new ContentValues();
    	ContentValues roValues = new ContentValues();
    	
    	/** Default the day to the first and the time zero'd out */
    	roDate.set(Calendar.DAY_OF_MONTH, 1);
    	roDate.set(Calendar.HOUR, 0);
    	roDate.set(Calendar.MINUTE, 0);
    	roDate.set(Calendar.SECOND, 0);
    	roDate.set(Calendar.MILLISECOND, 0);
    	stopDate.set(Calendar.DAY_OF_MONTH, 1);
    	stopDate.set(Calendar.HOUR, 0);
    	stopDate.set(Calendar.MINUTE, 0);
    	stopDate.set(Calendar.SECOND, 0);
    	stopDate.set(Calendar.MILLISECOND, 0);
    	
    	/** Default ContentValues for a time and roll over entry */
    	timeValues.put(Time.PUBLISHER_ID, _publisherID);
    	timeValues.put(Time.HOUSEHOLDER_ID, 0);
    	timeValues.put(Time.ENTRY_TYPE_ID, EntryType.ROLLOVER_ID);
    	timeValues.put(Time.TOTAL_HOURS, 1);
    	timeValues.put(Time.RETURN_VISITS, 0);
    	/** Will be replaced during the loop */
    	timeValues.put(Time.DATE, "");
    	/** Midnight */
    	timeValues.put(Time.TIME_START, "00:00");
    	/** 1 AM */
    	timeValues.put(Time.TIME_END, "01:00");
    	
    	roValues.put(Rollover.PUBLISHER_ID, _publisherID);
    	/** Will be replaced during the loop */
    	roValues.put(Rollover.DATE, "");
    	/** Will be replaced during the loop */
    	roValues.put(Rollover.MINUTES, 0);
    	
    	/** Prepare for the while loop by getting the previous month's minutes if they exist. */
    	roDate.add(Calendar.MONTH, -1);
    	database.openWritable();
    	Cursor record = database.fetchRolloverMinutes(_publisherID, saveDateFormat.format(roDate.getTime()));
    	if(record.moveToFirst())
    		previousMinutes = record.getDouble(record.getColumnIndex(Rollover.MINUTES));
    	record.close();
    	/** Add the month back that we took away to get the previous months minutes */
    	roDate.add(Calendar.MONTH, 1);
    	
    	/** Compare values
		 *  0 if the times of the two Calendars are equal
		 *  -1 if the time of this Calendar is before the other one
		 *  1 if the time of this Calendar is after the other one
		 */
    	/** This loop will run while the date is less than or equal to now() */
    	while (roDate.compareTo(stopDate) != 1) {
    		/** Reset the ID's */
    		rolloverTimeID = 0;
    		rolloverID = 0;
    		sum = 0;
    		
    		/** Save the dates */
    		timeValues.put(Time.DATE,saveDateFormat.format(roDate.getTime()));
    		roValues.put(Rollover.DATE,saveDateFormat.format(roDate.getTime()));
    		
    		/** Is there already a rollover time entry for this month? If so we need that time entry _id */
			record = database.fetchRolloverTimeEntry(saveDateFormat.format(roDate.getTime()), _publisherID);
			if(record.moveToFirst())
				rolloverTimeID = record.getInt(record.getColumnIndex(Time._ID));
			record.close();
			
			/** Is there already a roll over entry for this month? If so we need that rollover entry _id */
			record = database.fetchRolloverMinutes(_publisherID, saveDateFormat.format(roDate.getTime()));
			if(record.moveToFirst())
				rolloverID = record.getInt(record.getColumnIndex(Rollover._ID));
			record.close();
			
			/** Get month's hours */
			sum = database.fetchHoursForMonthForPublisher(saveDateFormat.format(roDate.getTime()), _publisherID);
			currentMinutes = sum - (int) sum;
			
			/** If the minutes add up to be over an hour we need to create/update the roll over time entry */
			if(currentMinutes + previousMinutes >= 1) {
				/** Update record */
				if(rolloverTimeID != 0)
					database.updateTimeEntry(rolloverTimeID, timeValues);
				/** Create record */
				else
					database.createTimeEntry(timeValues);
				/** Save the remainder of minutes. */
				previousMinutes += currentMinutes - 1;
			}
			
			/** We need to delete the time entry if it exists */
			else if(rolloverTimeID != 0) {
				database.removeTimeEntry(rolloverTimeID);
				previousMinutes += currentMinutes;
			}
			else
				previousMinutes += currentMinutes;
			
			roValues.put(Rollover.MINUTES, previousMinutes);
			
			/** Update record */
			if(rolloverID != 0)
				database.updateRolloverMinutes(rolloverID, roValues);
			/** Create record */
			else
				database.createRolloverMinutes(roValues);
    		
    		/** Increase the date by a month */
    		roDate.add(Calendar.MONTH, 1);
    	}
    	database.close();
    }
    
    public static class LitEntry {
    	private int id;
    	private int publisherID;
    	private int litNameID;
    	private String name;
    	private int householderID;
    	private int count;
    	
    	public LitEntry(int _id,String _name,int _litNameID,int _count) {
    		id = _id;
    		name = _name;
    		litNameID = _litNameID;
    		count = _count;
    	}
    	
    	@Override
		public String toString() {
    		return count + " - " + name;
    	}
    	
    	public int getID() { return id; }
    	public void setID(int _id) { id = _id; }
    	
    	public int getPublisherID() { return publisherID; }
    	public void setPublisherID(int _publisherID) { publisherID = _publisherID; }
    	
    	public int getHouseholderID() { return householderID; }
    	public void setHouseholderID(int _householderID) { householderID = _householderID; }
    	
    	public int getLitNameID() { return litNameID; }
    	public void setLitNameID(int _litNameID) { litNameID = _litNameID; }
    	
    	public String getLitName() { return name; }
    	public void setLitName(String _name) { name = _name; }
    	
    	public int getCount() { return count; }
    	public void setCount(int _count) { count = _count; }
    	
    	public void setLitNameAndID(String _name, int _litNameID) { name = _name; litNameID = _litNameID; }
    }
	
	public void showDialog() {
		/** DialogFragment.show() will take care of adding the fragment
		 * in a transaction. We also want to remove any currently showing
		 * dialogs, so make our own transaction and take care of that here. */
		FragmentTransaction ft = getSupportFragmentManager().beginTransaction();
		Fragment prev = getSupportFragmentManager().findFragmentByTag("dialog");
		if(prev != null)
			ft.remove(prev);
		ft.addToBackStack(null);
		/** Create and show the dialog. */
		DialogFrag newFragment = DialogFrag.newInstance(getApplicationContext().getString(R.string.menuPublishers), DialogFrag.ACTIVE_PUBLISHERS);
		newFragment.show(getSupportFragmentManager(), "dialog");
	}
	
	public void createNewPublisherShowDialog() {
		/** DialogFragment.show() will take care of adding the fragment
		 * in a transaction. We also want to remove any currently showing
		 * dialogs, so make our own transaction and take care of that here. */
		FragmentTransaction ft = getSupportFragmentManager().beginTransaction();
		Fragment prev = getSupportFragmentManager().findFragmentByTag("dialog");
		if(prev != null)
			ft.remove(prev);
		ft.addToBackStack(null);
		/** Create and show the dialog. */
		DialogFrag newFragment = DialogFrag.newInstance(getApplicationContext().getString(R.string.publishersName), DialogFrag.CREATE_PUBLISHER);
		newFragment.show(getSupportFragmentManager(), "dialog");
	}
	
	public void sendArrayToActivity(ArrayList<LitEntry> list) {
		selectedLiterature = list;	
	}
	
	public void save() {
		if(saveTime()) {
			selectedDate.add(Calendar.MONTH, -1);
			Intent intent = new Intent(getApplicationContext(), Summary.class);
			intent.putExtra("month", selectedDate.get(Calendar.MONTH));
			intent.putExtra("year", selectedDate.get(Calendar.YEAR));
			startActivity(intent);
			finish();
		}
	}
}